#ifndef COMMAND_CONNECTION_HPP
#define COMMAND_CONNECTION_HPP

#include "connection.hpp"
#include "command.hpp"

namespace lge2d
{
namespace lan
{

// соединение, работающее с командами. Обертка вокруг обычного connection
// и CommandProcessor
// TODO: оптимизировать, убрав лишние копирования
class CommandConnection : public sf::NonCopyable
{
	typedef std::map<size_t, CommandHandlerBase*> HandlersMap_t;

public:

	CommandConnection();
	virtual ~CommandConnection();

	// подключение к серверу
	Connection::ErrorCode Connect(const std::string& host,
			unsigned short port = DEFAULT_SERVER_PORT,
			float timeOut = CLIENT_CONNECTIONG_TIMEOUT);

	// разрыв соединения
	void Disconnect();

	Connection::ErrorCode GetLastError() const;
	const Connection::Statictics& GetStatistics() const;
	bool IsConnected() const;

	bool Update(float dt);

	template<class TObject ,class TCommand>
	void RegisterHandler(CommandHandler<TObject, TCommand>* handler)
	{
		m_handlers[TCommand::ID] = handler;
	}

	template<class TCommand>
	void Send(const TCommand& cmd)
	{
		Packet packet;
		packet << TCommand::ID;
		packet << cmd;

		m_connection.Send(packet);
	}

private:

	void OnPacket(Packet& packet)
	{
		unsigned commandIdx(0);
		packet >> commandIdx;

		HandlersMap_t::iterator it = m_handlers.find(commandIdx);
		if (it != m_handlers.end())
		{
			(*(it->second))(packet);
		}
		else
		{
			lge2d::log->Error("Command handler with id = %d not found.", commandIdx);
		}
	}

private:
	Connection m_connection;
	HandlersMap_t m_handlers;
};

} /* namespace lan */
} /* namespace lge2d */

#endif /* COMMAND_CONNECTION_HPP */
